use math::MOD;

mod input {
    use std::io::stdin;

    pub fn one() -> i64 {
        let mut buf = String::new();
        stdin().read_line(&mut buf).expect("Failed to read line");
        return buf.trim().parse().expect("Invalid input");
    }

    pub fn vec() -> Vec<i64> {
        let mut buf = String::new();
        stdin().read_line(&mut buf).expect("Failed to read line");
        return buf
            .split_whitespace()
            .map(|s| s.parse().expect("Invalid input"))
            .collect();
    }

    pub fn two() -> (i64, i64) {
        let v = vec();
        (v[0], v[1])
    }

    pub fn thr() -> (i64, i64, i64) {
        let v = vec();
        (v[0], v[1], v[2])
    }

    pub fn fou() -> (i64, i64, i64, i64) {
        let v = vec();
        (v[0], v[1], v[2], v[3])
    }
}

mod algo {
    pub fn next_permutation<T: Ord>(nums: &mut [T]) -> bool {
        if nums.len() < 2 {
            return false;
        }
        let mut i = nums.len() - 2;
        while i != usize::MAX && nums[i] >= nums[i + 1] {
            if i == 0 {
                break;
            }
            i -= 1;
        }
        if nums[i] >= nums[i + 1] && i == 0 {
            nums.reverse();
            return false;
        }
        let mut j = nums.len() - 1;
        while nums[j] <= nums[i] {
            j -= 1;
        }
        nums.swap(i, j);
        nums[i + 1..].reverse();
        true
    }

    pub fn iota(start: i64, n: i64) -> impl Iterator<Item = i64> {
        (0..n).map(move |i| start + i)
    }
}

mod math {
    pub static mut MOD: i64 = 0;
    pub static mut pw: Vec<i64> = vec![];

    pub fn pow(mut x: i64, mut p: i64) -> i64 {
        let mut res = 1;
        while p > 1 {
            if p & 1 == 1 {
                res *= x;
            }
            x *= x;
            p >>= 1;
        }
        return res;
    }

    pub fn exgcd(a: i64, b: i64) -> (i64, i64, i64) {
        if b == 0 {
            (a, 1, 0)
        } else {
            let (d, x1, y1) = exgcd(b, a % b);
            (d, y1, x1 - (a / b) * y1)
        }
    }

    pub fn modinv(a: i64) -> i64 {
        unsafe {
            let (_, x, _) = exgcd(a, MOD);
            (x % MOD + MOD) % MOD
        }
    }

    pub fn init(n: i64, m: i64) {
        unsafe {
            MOD = m;
            pw = vec![0; n as usize + 1];
            pw[0] = 1;
            for i in 1..=n as usize {
                pw[i] = (pw[i - 1] * i as i64) % MOD;
            }
        }
    }

    pub fn comb(n: i64, m: i64) -> i64 {
        unsafe {
            let n = n as usize;
            let m = m as usize;
            pw[n] * modinv(pw[m]) % MOD * modinv(pw[n - m]) % MOD
        }
    }

    pub fn comb_brute(n: i64, mut m: i64) -> i64 {
        unsafe {
            if m > n - m {
                m = n - m;
            }
            let mut res: i64 = 1;
            for i in 1..=m {
                res = res * (n - i + 1) / i % MOD;
            }
            res
        }
    }
}

fn main() {
    unsafe {
        let (mut T, m) = input::two();

        let si = 5005;
        let mut comb = vec![vec![0i64; si]; si];
        for i in 0..si {
            comb[i][0] = 1;
            comb[i][i] = 1;
            for j in 1..i {
                comb[i][j] = (comb[i - 1][j - 1] + comb[i - 1][j]) % m;
            }
        }

        while T > 0 {
            T -= 1;

            let n = input::one();
            let a = input::vec();
            let mut s: i64 = a.iter().sum();

            let mut res = 1;
            for i in a {
                res *= comb[s as usize][i as usize];
                res %= MOD;
                s -= i;
            }

            println!("{}", res);
        }
    }
}
